﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Globalization;
using System.Collections;

namespace VSM.Business.Parts.Purchasing
{
    public partial class MRP : System.Web.UI.Page
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            this.Page.Title = "MRP Part";
            string dateFormat = "MMM-yy";
            try
            {
                if (!IsPostBack)
                {
                    BindData(BuildContents(null));
                    this.txtRunDate.Text = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss tt");
                    this.txtRunDate.Enabled = false;
                    this.grvFCT1.Columns[11].HeaderText = DateTime.Now.AddMonths(-6).ToString(dateFormat, CultureInfo.CreateSpecificCulture("en-US"));
                    this.grvFCT1.Columns[12].HeaderText = DateTime.Now.AddMonths(-5).ToString(dateFormat, CultureInfo.CreateSpecificCulture("en-US"));
                    this.grvFCT1.Columns[13].HeaderText = DateTime.Now.AddMonths(-4).ToString(dateFormat, CultureInfo.CreateSpecificCulture("en-US"));
                    this.grvFCT1.Columns[14].HeaderText = DateTime.Now.AddMonths(-3).ToString(dateFormat, CultureInfo.CreateSpecificCulture("en-US"));
                    this.grvFCT1.Columns[15].HeaderText = DateTime.Now.AddMonths(-2).ToString(dateFormat, CultureInfo.CreateSpecificCulture("en-US"));
                    this.grvFCT1.Columns[16].HeaderText = DateTime.Now.AddMonths(-1).ToString(dateFormat, CultureInfo.CreateSpecificCulture("en-US"));
                    if (Session[Utils.AppConstants.ID_Dealer].ToString() == "VSM")
                    {
                        this.radEO.Visible = false;
                        this.radMO.Visible = false;
                    }
                    else
                    {
                        this.radAir.Visible = false;
                        this.radSea.Visible = false;
                        this.dllType.Visible = false;
                        this.grvFCT1.Columns[27].Visible = false;
                        this.grvFCT1.Columns[28].Visible = false;
                    }
                }
            }
            catch (Exception ex)
            {
                ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "OKErrors", "Main.setMasterMessage('" + ex.ToString() + "','');", true);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dtContent"></param>
        /// <returns></returns>
        private DataTable BuildContents(DataTable dtContent)
        {
            DataTable dt = new DataTable("FCT1");
            try
            {
                dt.Columns.Add("No");
                dt.Columns.Add("U_ModelSales");
                dt.Columns.Add("U_ProductSales");
                dt.Columns.Add("ModelName");
                dt.Columns.Add("ProductName");
                dt.Columns.Add("VendorCode");
                dt.Columns.Add("VendorName");
                dt.Columns.Add("ForeCastQty");
                dt.Columns.Add("MinStock");
                dt.Columns.Add("SOQty");
                dt.Columns.Add("POQty");
                dt.Columns.Add("InHand");
                dt.Columns.Add("MRP");
            }
            catch (Exception ex)
            {
                ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "OKErrors", "Main.setMasterMessage('" + ex.ToString() + "','');", true);
            }
            return dt;

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="tblData"></param>
        private void BindData(DataTable tblData)
        {
            Session["MRPParts"] = tblData;
            this.grvFCT1.DataSource = tblData;
            this.grvFCT1.DataBind();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnSave_Click(object sender, EventArgs e)
        {

        }
        protected void grvSearchResult_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                e.Row.Attributes.Add("onmouseover", "MouseEvents(this, event)");
                e.Row.Attributes.Add("onmouseout", "MouseEvents(this, event)");
                e.Row.Attributes["style"] = "cursor:pointer";
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="AbsID"></param>
        /// <param name="NewDocType"></param>
        /// <param name="startDate"></param>
        /// <param name="endDate"></param>
        private void LoadData(string dbType)
        {
            try
            {
                MasterData obj = new MasterData();
                DataSet dsConfig = obj.GetConfig("VSM", Session[Utils.AppConstants.ID_Dealer].ToString());

                GeneralFunctions GF = new GeneralFunctions(dbType, Session[Utils.AppConstants.ID_Dealer].ToString());
                DataTable dtWhs = GF.GetWarehouseByDealerDepartment(dbType, Session[Utils.AppConstants.ID_Dealer].ToString(), Utils.AppConstants.PARTS);
                string warehouse = dtWhs.Rows[0]["WhsCode"].ToString();
                if (Session[Utils.AppConstants.WhsCode] != null)
                {
                    warehouse = Session[Utils.AppConstants.WhsCode].ToString();
                }
                DataSet dsInvoice = obj.GetPartARInvoiceItems(dbType, warehouse);
                DataSet dsInternalTranfer = null;
                dsInternalTranfer = obj.GetInternalInventoryTransfer(dbType, warehouse);
                DataSet returnDoc = obj.GetMRPItemPartByWareHouse(dbType, warehouse, Session[Utils.AppConstants.U_Department].ToString());


                double oc, lt, a, b, c, d;
                a = b = 1;
                c = d = 0.5;
                if (dbType == "VSM")
                {
                    oc = 1;
                    lt = 4;
                }
                else
                {
                    oc = 0.5;
                    lt = 1;
                }
                if (dsConfig != null && dsConfig.Tables.Count > 0 && dsConfig.Tables[0].Rows.Count > 0)
                {
                    oc = double.Parse(dsConfig.Tables[0].Rows[0]["OC"].ToString());
                    lt = double.Parse(dsConfig.Tables[0].Rows[0]["LT"].ToString());
                    a = double.Parse(dsConfig.Tables[0].Rows[0]["MRPA"].ToString());
                    b = double.Parse(dsConfig.Tables[0].Rows[0]["MRPB"].ToString());
                    c = double.Parse(dsConfig.Tables[0].Rows[0]["MRPC"].ToString());
                    d = double.Parse(dsConfig.Tables[0].Rows[0]["MRPD"].ToString());
                }
                if (returnDoc != null && returnDoc.Tables.Count > 0)
                {
                    DataTable tb = returnDoc.Tables[0];
                    tb.Columns.Add("Cumulated");
                    tb.Columns.Add("TargetFillRate");
                    tb.Columns.Add("ClassType");
                    tb.Columns.Add("No");
                    tb.Columns.Add("M1");
                    tb.Columns.Add("M2");
                    tb.Columns.Add("M3");
                    tb.Columns.Add("M4");
                    tb.Columns.Add("M5");
                    tb.Columns.Add("M6");
                    tb.Columns.Add("M7");
                    tb.Columns.Add("AvgMon");
                    tb.Columns.Add("StandardDeviation");
                    tb.Columns.Add("ServiceRate");
                    tb.Columns.Add("LeadtimeFactor");
                    tb.Columns.Add("SS");
                    tb.Columns.Add("MaxPoint");
                    tb.Columns.Add("OrdrIntrvlDisplay");
                    tb.Columns.Add("OrderPoint", typeof(System.Double));
                    tb.Columns.Add("WarningPoint");
                    tb.Columns.Add("OrderQty", typeof(System.Double));
                    tb.Columns.Add("OnHandOrderQty", typeof(System.Double));

                    double temp = 0;
                    double cumulate = 0;
                    int i = 1;
                    double D = 0;
                    double warningPoint = 0;
                    double onHand = 0;
                    double orderQty = 0;
                    DataTable tbImport = tb.Clone();
                    if (tb.Rows.Count > 0)
                    {
                        foreach (DataRow r in tb.Rows)
                        {
                            r["Cumulated"] = 0;
                            if (r["OpenPO"].ToString().Length > 0
                                && r["OpenSO"].ToString().Length > 0
                                && r["Cumulated"].ToString().Length > 0)
                            {

                                //OC
                                if (r["OrdrIntrvl"].ToString().Length == 0)
                                {
                                    r["OrdrIntrvl"] = oc;
                                    r["OrdrIntrvlDisplay"] = oc;
                                }
                                //LT
                                if (r["LeadTime"].ToString().Length == 0)
                                {
                                    r["LeadTime"] = lt;
                                }

                                //Service Rate
                                r["ServiceRate"] = 1.65;

                                //Leadtime Factor
                                r["LeadtimeFactor"] = Math.Sqrt(double.Parse(r["LeadTime"].ToString()));

                                //Cumulate
                                cumulate = temp + (r["NumberLine"].ToString() != "" ? double.Parse(r["NumberLine"].ToString()) : 0);
                                r["Cumulated"] = GF.FormatNumeric(cumulate.ToString(), "QtyDec");
                                r["NumberLine"] = GF.FormatNumeric(r["NumberLine"].ToString(), "QtyDec");
                                r["OnHand"] = GF.FormatNumeric(r["OnHand"].ToString(), "QtyDec");
                                r["No"] = i.ToString();

                                //Default Month
                                r["M1"] = 0;
                                r["M2"] = 0;
                                r["M3"] = 0;
                                r["M4"] = 0;
                                r["M5"] = 0;
                                r["M6"] = 0;
                                r["M7"] = 0;

                                //Invoice
                                DataRow[] rInvoice = dsInvoice.Tables[0].Select("ItemCode='" + r["ItemCode"].ToString() + "'");
                                if (rInvoice.Length > 0)
                                {
                                    foreach (DataRow rU in rInvoice)
                                    {
                                        r["M" + rU["No"]] = GF.FormatNumeric(rU["Quantity"].ToString(), "QtyDec");
                                    }
                                }
                                //Internal Invetory Transfer
                                DataRow[] rInventoryTranfer = dsInternalTranfer.Tables[0].Select("ItemCode='" + r["ItemCode"].ToString() + "'");
                                if (rInventoryTranfer.Length > 0)
                                {
                                    foreach (DataRow rU in rInventoryTranfer)
                                    {
                                        double m = double.Parse(r["M" + rU["No"]].ToString()) + double.Parse(rU["Quantity"].ToString());
                                        r["M" + rU["No"]] = GF.FormatNumeric(m.ToString(), "QtyDec");
                                    }
                                }
                                //AvgMon
                                double avgMon = (double.Parse(r["M1"].ToString()) +
                                    double.Parse(r["M2"].ToString()) +
                                    double.Parse(r["M3"].ToString()) +
                                    double.Parse(r["M4"].ToString()) +
                                    double.Parse(r["M5"].ToString()) +
                                    double.Parse(r["M6"].ToString())) / 6;
                                r["AvgMon"] = Math.Round(avgMon, 4);// GF.FormatNumeric(avgMon.ToString(), "PriceDec");
                                //Standard Deviation
                                List<double> listMon = new List<double>() { double.Parse(r["M1"].ToString()), double.Parse(r["M2"].ToString()),
                            double.Parse(r["M3"].ToString()),
                            double.Parse(r["M4"].ToString()),
                            double.Parse(r["M5"].ToString()),
                            double.Parse(r["M6"].ToString())};
                                double standardDeviation = StandardDeviation(listMon);
                                r["StandardDeviation"] = Math.Round(standardDeviation, 5);
                                D = (double.Parse(r["M1"].ToString()) +
                               double.Parse(r["M2"].ToString()) +
                               double.Parse(r["M3"].ToString()) +
                               double.Parse(r["M4"].ToString()) +
                               double.Parse(r["M5"].ToString()) +
                               double.Parse(r["M6"].ToString()));
                                //SS
                                double ss = 0;
                                if (dbType == "VSM")
                                {
                                    if (avgMon != 0)
                                    {
                                        ss = (standardDeviation * 1.65 * 2) / avgMon;
                                    }
                                }
                                else
                                {
                                    ss = SSDefine(D, avgMon);
                                }
                                r["SS"] = Math.Round(ss, 5);

                                //Max Point
                                double maxpoint = (avgMon * oc) + (avgMon * (lt + ss));
                                r["MaxPoint"] = Math.Round(maxpoint, 5);

                                //Order Point
                                double orderpoint = (avgMon * (lt + ss));
                                r["OrderPoint"] = Math.Round(orderpoint, 5);

                                //Warning Point
                                if (dbType == "VSM")
                                {
                                    if (this.radSea.Checked)
                                    {
                                        if (r["U_Class"].ToString() == "M" || r["U_Class"].ToString() == "S")
                                        {
                                            warningPoint = avgMon * 1;
                                        }
                                        else if (r["U_Class"].ToString() == "F")
                                        {
                                            warningPoint = avgMon * 0.5;
                                        }
                                    }
                                    else
                                    {
                                        warningPoint = avgMon * a;
                                    }
                                }
                                else
                                {
                                    if (this.radMO.Checked)
                                    {
                                        if (r["U_Class"].ToString() == "M" || r["U_Class"].ToString() == "S")
                                        {
                                            warningPoint = avgMon * 1;
                                        }
                                        else if (r["U_Class"].ToString() == "F")
                                        {
                                            warningPoint = avgMon * 0.5;
                                        }
                                    }
                                    else
                                    {
                                        warningPoint = avgMon * c;
                                    }
                                }
                                r["WarningPoint"] = Math.Round(warningPoint, 5);

                                //Order Qty

                                if (r["OnHand"].ToString().Length > 0)
                                {
                                    onHand = double.Parse(r["OnHand"].ToString());
                                }


                                if (dbType == "VSM")
                                {
                                    if (this.radSea.Checked)
                                    {
                                        orderQty = maxpoint - (onHand + double.Parse(r["OpenPO"].ToString()) - double.Parse(r["OpenSO"].ToString()));
                                    }
                                    else
                                    {
                                        orderQty = avgMon * b;
                                    }
                                }
                                else
                                {
                                    if (this.radMO.Checked)
                                    {
                                        orderQty = maxpoint - (onHand + double.Parse(r["OpenPO"].ToString()) - double.Parse(r["OpenSO"].ToString()));
                                    }
                                    else
                                    {
                                        orderQty = avgMon * d;
                                    }
                                }
                                r["OrderQty"] = Math.Ceiling(orderQty);
                                //
                                r["OnHandOrderQty"] = onHand + orderQty;
                            }
                            if (D != 0)
                            {
                                temp = cumulate;
                                i++;
                                if (dbType != "VSM")
                                {
                                    if (this.radEO.Checked)
                                    {
                                        if (warningPoint >= onHand && warningPoint <= orderQty)
                                        {
                                            tbImport.ImportRow(r);
                                        }
                                    }
                                    else
                                    {
                                        tbImport.ImportRow(r);
                                    }
                                }
                                else
                                {
                                    tbImport.ImportRow(r);
                                }
                            }
                        }
                        if (tbImport.Rows.Count > 0)
                        {
                            double CumulatedMax = double.Parse(tbImport.Rows[tbImport.Rows.Count - 1]["Cumulated"].ToString());

                            foreach (DataRow r in tbImport.Rows)
                            {
                                if (r["OpenPO"].ToString().Length > 0
                                   && r["OpenSO"].ToString().Length > 0
                                   && r["Cumulated"].ToString().Length > 0)
                                {
                                    string classType = string.Empty;
                                    double TargetFillRate = (double.Parse(r["Cumulated"].ToString()) / CumulatedMax) * 100;

                                    if (TargetFillRate < 80)
                                    {
                                        classType = "A";
                                    }
                                    else if (TargetFillRate < 95)
                                    {
                                        classType = "B";
                                    }
                                    else if (TargetFillRate <= 100)
                                    {
                                        classType = "C";
                                    }

                                    r["TargetFillRate"] = Math.Round(TargetFillRate) + "%";
                                    r["ClassType"] = classType;
                                }
                            }
                            BindData(tbImport);
                        }
                    }
                    else
                    {
                        ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "OKErrors", "Main.setMasterMessage('" + "Can not found data." + "','');", true);
                    }
                }
            }
            catch (Exception ex)
            {
                ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "OKErrors", "Main.setMasterMessage('" + ex.ToString() + "','');", true);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="SOQty"></param>
        /// <param name="avgMon"></param>
        /// <returns></returns>
        private double SSDefine(double SOQty, double avgMon)
        {
            if (avgMon >= 6)
            {
                return 0.4;
            }
            else
            {
                if (SOQty >= 27 && SOQty <= 32)
                {
                    return 0.5;
                }
                if (SOQty >= 21 && SOQty <= 26)
                {
                    return 0.6;
                }
                if (SOQty >= 15 && SOQty <= 20)
                {
                    return 0.7;
                }
                if (SOQty >= 9 && SOQty <= 14)
                {
                    return 0.8;
                }
                if (SOQty >= 4 && SOQty <= 8)
                {
                    return 1;
                }
                if (SOQty == 3)
                {
                    return 1.1;
                }
                if (SOQty >= 1 && SOQty <= 2)
                {
                    return 1.1;
                }
            }
            return 0;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        private double StandardDeviation(IEnumerable<double> values)
        {
            double avg = values.Average();
            return Math.Sqrt(values.Average(v => Math.Pow(v - avg, 2)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void grvFCT1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            this.grvFCT1.PageIndex = e.NewPageIndex;
            DataTable tblIPO = (DataTable)Session["MRPParts"];
            BindData(tblIPO);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnRun_Click(object sender, EventArgs e)
        {
            try
            {
                string dbType = Session[Utils.AppConstants.ID_Dealer].ToString() == "VSM" ? Utils.AppConstants.VSM : Utils.AppConstants.DEALER;
                LoadData(dbType);
            }
            catch (Exception ex)
            {
                ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "OKErrors", "Main.setMasterMessage('" + ex.ToString() + "','');", true);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnPOList_Click(object sender, EventArgs e)
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void dllType_SelectedIndexChanged(object sender, EventArgs e)
        {
            FilterData();
        }
        /// <summary>
        /// 
        /// </summary>
        private void FilterData()
        {
            try
            {
                DataTable tblData = (DataTable)Session["MRPParts"];
                if (tblData != null)
                {
                    if (this.dllType.SelectedValue == "A")
                    {
                        DataView dv = tblData.Copy().DefaultView;
                        dv.RowFilter = "OrderQty>0";
                        this.grvFCT1.DataSource = dv.ToTable();
                        this.grvFCT1.DataBind();
                    }
                    else if (this.dllType.SelectedValue == "B")
                    {
                        DataView dv = tblData.Copy().DefaultView;
                        dv.RowFilter = "OnHandOrderQty<=OrderPoint";
                        this.grvFCT1.DataSource = dv.ToTable();
                        this.grvFCT1.DataBind();
                    }
                    else if (this.dllType.SelectedValue == "C")
                    {
                        DataTable tb = tblData.Clone();

                        foreach (DataRow r in tblData.Rows)
                        {
                            if (r["U_Class"].ToString() == "F")
                            {
                                if (double.Parse(r["OrderQty"].ToString()) > 0)
                                {
                                    tb.ImportRow(r);
                                }
                            }
                            else
                            {
                                if (double.Parse(r["OnHandOrderQty"].ToString()) <= double.Parse(r["OrderPoint"].ToString()))
                                {
                                    tb.ImportRow(r);
                                }
                            }
                        }
                        this.grvFCT1.DataSource = tb;
                        this.grvFCT1.DataBind();
                    }
                    else
                    {
                        this.grvFCT1.DataSource = tblData;
                        this.grvFCT1.DataBind();
                    }
                }
            }
            catch (Exception ex)
            {
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void radSea_CheckedChanged(object sender, EventArgs e)
        {
            this.dllType.Visible = true;
            BindData(null);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void radAir_CheckedChanged(object sender, EventArgs e)
        {
            this.dllType.Visible = false;
            this.dllType.SelectedIndex = 0;
            BindData(null);
        }

        protected void radMO_CheckedChanged(object sender, EventArgs e)
        {
            BindData(null);
        }

        protected void radEO_CheckedChanged(object sender, EventArgs e)
        {
            BindData(null);
        }
    }
}